home *** CD-ROM | disk | FTP | other *** search
- ; STANDARD.S
- ;************************************************************************
- ;* *
- ;* PC Scheme/Geneva 4.00 Scheme code *
- ;* *
- ;* (c) 1985-1988 by Texas Instruments, Inc. See COPYRIGHT.TXT *
- ;* (c) 1992 by L. Bartholdi & M. Vuilleumier, University of Geneva *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Standard Scheme Routines *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Created by: David Bartley Date: 1985 *
- ;* Revision history: *
- ;* - 10 Feb 87: BOOLEAN? and PROCEDURE? added for R^3 Report (tc) *
- ;* - 1 Jun 87: separated PSTD and PSTD2 for compiler-less system (tc) *
- ;* - 9 Jun 87: made list-tail a primitive operation (tc) *
- ;* - 18 Jun 92: Renaissance (Borland Compilers, ...) *
- ;* - 23 Dec 92: Added R^4 support (apply f ...), (map f ...) (lb & mv) *
- ;* - 9 Jan 93: Added LIST? for R^4, and CIRCULAR-LIST? (mv) *
- ;* Changed REVERSE! to recognize circular lists (mv) *
- ;* *
- ;* ``In nomine omnipotentii dei'' *
- ;************************************************************************
-
- (define reverse! ; REVERSE!
- (lambda (l)
- (let ((ll (%reverse! l)))
- (if (if (and (eq? ll l) (pair? (cdr ll))) ; see CIRCULAR-LIST? below
- #T
- (not (null? (cdr l))))
- (%error-invalid-operand 'REVERSE! (%reverse! ll))
- ll))))
-
- (begin
- (define-integrable 1+ ; 1+
- (lambda (n) (+ n 1)))
-
- (define-integrable -1+ ; -1+
- (lambda (n) (- n 1)))
-
- (define-integrable add1 ; ADD1
- (lambda (n) (+ n 1)))
-
- (define-integrable apply ; APPLY
- (lambda (proc . args)
- (define sgra (%reverse! (%append args '())))
- (%apply proc (%append (%reverse! (cdr sgra)) (car sgra)))))
-
- (define-integrable caaaar (lambda (x) (caar (caar x)))) ; CAXXXR
- (define-integrable caaadr (lambda (x) (caar (cadr x))))
- (define-integrable caadar (lambda (x) (caar (cdar x))))
- (define-integrable caaddr (lambda (x) (caar (cddr x))))
- (define-integrable cadaar (lambda (x) (cadr (caar x))))
- (define-integrable cadadr (lambda (x) (cadr (cadr x))))
- (define-integrable caddar (lambda (x) (cadr (cdar x))))
- ; (define-integrable cadddr (lambda (x) (cadr (cddr x)))) ; opcode
-
- (define-integrable call/cc ; CALL/CC
- (lambda (exp)
- (%call/cc exp)))
-
- (define-integrable call-with-current-continuation ; CALL-w-c-c
- (lambda (exp)
- (%call/cc exp)))
-
- (define-integrable cdaaar (lambda (x) (cdar (caar x)))) ; CDXXXR
- (define-integrable cdaadr (lambda (x) (cdar (cadr x))))
- (define-integrable cdadar (lambda (x) (cdar (cdar x))))
- (define-integrable cdaddr (lambda (x) (cdar (cddr x))))
- (define-integrable cddaar (lambda (x) (cddr (caar x))))
- (define-integrable cddadr (lambda (x) (cddr (cadr x))))
- (define-integrable cdddar (lambda (x) (cddr (cdar x))))
- (define-integrable cddddr (lambda (x) (cddr (cddr x))))
-
- (define-integrable empty-stream? ; EMPTY-STREAM?
- (lambda (x)
- (eq? x the-empty-stream)))
-
- (define-integrable null? ; NULL?
- (lambda (obj)
- (not obj)))
-
- (define-integrable pair-reverse! %reverse!) ; PAIR-REVERSE!
-
- (define-integrable reverse ; REVERSE
- (lambda (l)
- (reverse! (%append l '()))))
-
- (define-integrable sub1 ; SUB1
- (lambda (n) (- n 1)))
-
- (define-integrable procedure? ; PROCEDURE?
- (lambda (obj)
- (proc? obj)))
- )
-
- (begin
- (define ascii->symbol ; ASCII->SYMBOL
- (lambda (n)
- (string->symbol (make-string 1 (integer->char n)))))
-
- (define (copy x) ; COPY
- (if (atom? x)
- x
- (cons (copy (car x))
- (copy (cdr x)))))
-
- (define %delay ; %DELAY
- (lambda (state)
- (lambda ()
- (when (closure? state) ; not yet memoized?
- (set! state (list (state))))
- (car state))))
-
- (define delayed-object? ; DELAYED-OBJECT?
- (lambda (obj)
- (and (vector? obj)
- (positive? (vector-length obj))
- (eq? (vector-ref obj 0) '#!DELAYED-OBJECT))))
-
- (define (delete! obj lst) ; DELETE!
- (letrec ((loop (lambda (obj a b z)
- (cond ((atom? b) z)
- ((equal? obj (car b))
- (set-cdr! a (cdr b))
- (loop obj a (cdr b) z))
- (else (loop obj b (cdr b) z))))))
- (cond ((atom? lst) '())
- ((equal? obj (car lst)) (delete! obj (cdr lst)))
- (else (loop obj lst (cdr lst) lst)))))
-
- (define (delq! obj lst) ; DELQ!
- (letrec ((loop (lambda (obj a b z)
- (cond ((atom? b) z)
- ((eq? obj (car b))
- (set-cdr! a (cdr b))
- (loop obj a (cdr b) z))
- (else (loop obj b (cdr b) z))))))
- (cond ((atom? lst) '())
- ((eq? obj (car lst)) (delq! obj (cdr lst)))
- (else (loop obj lst (cdr lst) lst)))))
-
- (define %execute ; %EXECUTE
- (lambda (compiled-object)
- (%%execute compiled-object))) ; dangerous primitive!
-
- (define exit ; EXIT
- (lambda args
- (transcript-off)
- (let ((code (if (null? (car args)) 0 (car args))))
- (if (= code 0)
- (with-output-to-file "history.ini"
- (lambda () (print `(push-history ',(get-history))))))
- (%halt code))
- (reset)))
-
- (define explode ; EXPLODE
- (lambda (obj)
- (let ((x (if (symbol? obj)
- (symbol->string obj)
- obj)))
- (cond ((string? x)
- (do ((x x x)
- (index 0 (add1 index))
- (end (string-length x) end)
- (result '()
- (cons (string->symbol (substring x index (+ index 1)))
- result)))
- ((= index end) (%reverse! result))))
- ((integer? x)
- (do ((n (abs x) (quotient n 10))
- (result '()
- (cons (ascii->symbol (+ (remainder n 10) 48))
- result)))
- ((< n 10)
- (let ((result (cons (ascii->symbol (+ n 48)) result)))
- (if (negative? x) (cons '- result) result)))))
- (else x)))))
-
- (define for-each ; FOR-EACH
- (lambda (f l)
- (do ((f f f)
- (l l (cdr l)))
- ((atom? l))
- (f (car l)))))
-
- (define force ; FORCE
- (lambda (obj)
- (if (and (vector? obj)
- (positive? (vector-length obj))
- (eq? (vector-ref obj 0) '#!DELAYED-OBJECT))
- ((vector-ref obj 1))
- (%error-invalid-operand 'FORCE obj))))
-
- (define gc ; GC
- (lambda args
- ;; do NOT define with define DEFINE-INTEGRABLE !!
- ;; do NOT hoist the call to %CLEAR-REGISTERS
- (cond ((or (null? args)
- (null? (car args)))
- (%clear-registers) ; unbind the VM registers
- (%garbage-collect)) ; invoke the GC operation
- (else
- (%clear-registers) ; unbind the VM registers
- (%compact-memory))))) ; GC and compaction both
-
- (define gcd ; GCD
- (lambda args
- (letrec ((gcd*
- (lambda (args result)
- (if (null? args)
- result
- (gcd* (cdr args)
- (gcd2 (abs (car args)) result)))))
- (gcd2
- (lambda (p q)
- (if (zero? q)
- p
- (gcd2 q (remainder p q))))))
- (gcd* args 0))))
-
- (define gensym ; GENSYM
- (letrec
- ((counter->string
- (lambda (c n)
- (cond ((positive? c)
- (let ((string (counter->string (quotient c 10) (+ n 1))))
- (string-set! string
- (- (string-length string) n 1)
- (string-ref "0123456789" (remainder c 10)))
- string))
- ((zero? n) "0")
- (else (make-string n '()))))))
- (let ((string "G")
- (counter -1))
- (lambda args
- (set! counter (+ counter 1))
- (when (not (null? args))
- (let ((arg (car args)))
- (cond ((integer? arg) (set! counter (abs arg)))
- ((string? arg) (set! string arg))
- ((symbol? arg) (set! string (symbol->string arg)))
- (else '()))))
- (string->uninterned-symbol
- (string-append string (counter->string counter 0)))))))
-
- (define head ; HEAD
- (lambda (stream)
- (if (and (vector? stream)
- (positive? (vector-length stream))
- (eq? (vector-ref stream 0) '#!STREAM))
- (vector-ref stream 1)
- (%error-invalid-operand 'HEAD stream))))
-
- (define implode ; IMPLODE
- (lambda (L)
- (cond ((null? L) '||)
- ((atom? L)
- (%error-invalid-operand 'implode L))
- (else
- (let ((n (length L)))
- (do ((L L (cdr L))
- (string (make-string n '()) string)
- (index 0 (add1 index)))
- ((null? L) (string->symbol string))
- (let* ((x (car L)))
- (string-set!
- string
- index
- (cond ((symbol? x) (string-ref (symbol->string x) 0))
- ((string? x) (string-ref x 0))
- ((char? x) x)
- ((integer? x) (integer->char x))
- (else (error "Invalid list element for IMPLODE" x)) )))))))))
-
- (define lcm ; LCM
- (letrec ((lcm*
- (lambda (args result)
- (if (null? args)
- result
- (let ((a (car args)))
- (if (zero? a)
- 0
- (lcm* (cdr args)
- (quotient (abs (* a result))
- (gcd a result)))))))))
- (lambda args
- (lcm* args 1))))
-
- (define (list->stream L) ; LIST->STREAM
- (if (null? L)
- the-empty-stream
- (let ((heapL L)) ; control heap allocation of L
- (cons-stream (car L)
- (list->stream (cdr heapL))))))
-
- (define list->vector ; LIST->VECTOR
- (lambda (L)
- (let ((n (length L)))
- (do ((v (make-vector n) v)
- (i 0 (1+ i))
- (L L (cdr L)))
- ((null? L) v)
- (vector-set! v i (car L))))))
-
- (define list-ref ; LIST-REF
- (lambda (x n)
- (car (list-tail x n))))
-
- ; List-tail was re-defined as a primitive on 6-9-87
- ;
- ; (define (list-tail x n) ; LIST-TAIL
- ; (if (positive? n)
- ; (list-tail (cdr x)(sub1 n))
- ; x))
-
- (define (map proc . l) ; MAP
- (do ((proc proc proc)
- (l l (do ((l l (cdr l))
- (n '() (cons (cdar l) n)))
- ((atom? l) (%reverse! n))))
- (a '() (cons (apply proc (do ((l l (cdr l))
- (n '() (cons (caar l) n)))
- ((atom? l) (%reverse! n))))
- a)))
- ((atom? (car l)) (%reverse! a))))
-
- (define mapc ; MAPC
- for-each)
-
- (define mapcar ; MAPCAR
- map)
-
- (define property ; PROPERTY
- (lambda (symbol . args)
- (cond ((null? args) (proplist symbol))
- ((null? (cadr args)) (getprop symbol (car args)))
- ((eq? (cadr args) '#!UNDEFINED) (remprop symbol (car args)))
- ((null? (caddr args)) (putprop symbol (cadr args) (car args)))
- (else (%error-invalid-operand 'property args)))))
-
- (define (random n) ; RANDOM
- (let* ((wordsize 32768)
- (prec (do ((i 0 (1+ i))
- (p 1 (* p wordsize)))
- ((>= p n) (cons p i))))
- (newrandom (named-lambda (newrandom i) (if (= i 0) 0 (+ (* wordsize (newrandom (-1+ i)))
- (%random)))))
- (bound (* n (quotient (car prec) n))))
- (if (<= n 0)
- (%error-invalid-operand 'random n))
- (do ((try (newrandom (cdr prec)) (newrandom (cdr prec))))
- ((< try bound) (remainder try n)))))
-
- (define (randomize . seed) ; RANDOMIZE
- (%esc 20 (if (integer? (car seed)) (car seed) -1)))
-
- (define clock ; CLOCK
- (lambda ()
- (%esc 43)))
- (define clock-tick
- (/ #x10000 (* 60 60)))
-
- (define time ; TIME services
- (let ((locale '()))
- (lambda (message . args)
- (let* ((locals '())
- (complete (named-lambda (complete source supply length)
- (if (= length 0)
- '()
- (let ((new (car (if (null? source) supply source))))
- (cons (apply-if (assq new (apply append locals))
- (lambda (e) (cdr e))
- new)
- (complete (cdr source) (cdr supply) (-1+ length)))))))
- (getunix (lambda args
- (cond ((null? args) (%esc 44))
- ((integer? (car args)) (car args))
- ((list? (car args))
- (let ((now (%esc 45 0 (%esc 44 0))))
- (apply %esc 46 0 (complete (car args) now 6))))
- (else (%error-invalid-operand 'TIME args)))))
- (set-at! (lambda (n l table)
- (let ((at (list-tail l n)))
- (apply-if (assq (car at)
- (map (lambda (pair)
- (cons (cdr pair) (car pair)))
- table))
- (lambda (e) (set-car! at (cdr e)))))))
- (dotime (lambda (mode . args)
- (let ((local (%esc 45 mode (getunix args))))
- (set-at! 4 local (car locals))
- (set-at! 6 local (cadr locals))
- (set-at! 8 local (caddr locals))
- local)))
- (jobs `((UNIX . ,(lambda args (apply getunix args)))
- (LOCAL . ,(lambda args (apply dotime 0 args)))
- (GM . ,(lambda args (apply dotime 1 args)))
- (COUNTRY . ,(lambda args
- (apply-if (assq (car args) locale)
- (lambda (e)
- (set! locale (delete! e locale))))
- (set! locale (cons args locale))))
- )))
- (apply-if (assq (car args) locale)
- (lambda (e)
- (set! locals (cdr e))
- (set! args (cdr args))))
- (apply-if (assq message jobs)
- (lambda (job) (apply (cdr job) args))
- (%error-invalid-operand 'TIME message))))))
-
- (time 'COUNTRY 'ENGLISH
- '((january . 0) (february . 1) (march . 2) (april . 3)
- (may . 4) (june . 5) (july . 6) (august . 7)
- (september . 8) (october . 9) (november . 10) (december . 11))
- '((sunday . 0) (monday . 1) (tuesday . 2) (wednesday . 3)
- (thursday . 4) (friday . 5) (saturday . 6))
- '((dst-on . 0) (dst-off . 1))
- )
- (time 'COUNTRY 'FRENCH
- '((janvier . 0) (fevrier . 1) (mars . 2) (avril . 3)
- (mai . 4) (juin . 5) (juillet . 6) (aout . 7)
- (septembre . 8) (octobre . 9) (novembre . 10) (decembre . 11))
- '((dimanche . 0) (lundi . 1) (mardi . 2) (mercredi . 3)
- (jeudi . 4) (vendredi . 5) (samedi . 6))
- '((sans-changement . 0) (changement . 1))
- )
-
- (define stream? ; STREAM?
- (lambda (obj)
- (or (eq? obj the-empty-stream)
- (and (vector? obj)
- (positive? (vector-length obj))
- (eq? (vector-ref obj 0) '#!STREAM)))))
-
- (define (stream->list stream) ; STREAM->LIST
- (if (empty-stream? stream)
- '()
- (cons (head stream)
- (stream->list (tail stream)))))
-
- (define symbol->ascii ; SYMBOL->ASCII
- (lambda (s)
- (char->integer (string-ref (symbol->string s) 0))))
-
- (define tail ; TAIL
- (lambda (stream)
- (if (and (vector? stream)
- (positive? (vector-length stream))
- (eq? (vector-ref stream 0) '#!STREAM))
- ((vector-ref stream 2))
- (%error-invalid-operand 'TAIL stream))))
-
- (define thaw ; THAW
- (lambda (thunk)
- (thunk)))
-
- (define vector->list ; VECTOR->LIST
- (lambda (v)
- (do ((n (vector-length v) n)
- (i 0 (1+ i))
- (L '() (cons (vector-ref v i) L)))
- ((>= i n)
- (%reverse! L)))))
-
- (define boolean? ; BOOLEAN?
- (lambda (obj)
- (or (eq? obj #T) (null? obj) #F)))
-
- (define circular-list? ; CIRCULAR-LIST?
- (lambda (l)
- (if (pair? l)
- (let* ((ll (%reverse! l)) ; when loop exists, reverse loop only
- (result (and (eq? ll l) ; ...and first cell stay unchanged
- (pair? (cdr ll)))))
- (%reverse! ll)
- result)
- #F)))
-
- (define list? ; LIST?
- (lambda (l) ; R4RS definition:
- (or (null? l)
- (if (or (atom? l) (circular-list? l)) ; end with a NULL
- #F
- (null? (cdr (last-pair l)))))))
- )
-